package com.zhangkang.stock.stocklib.details

import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.zhangkang.stock.stocklib.data.KDJ
import com.zhangkang.stock.stocklib.data.KLineInfo
import com.zhangkang.stock.stocklib.data.MACD
import com.zhangkang.stock.stocklib.databinding.StockActivityStockDetailsBinding
import com.zhangkang.stock.stocklib.tools.KDJTools
import com.zhangkang.stock.stocklib.tools.MACDTools
import com.zhangkang.stock.stocklib.tools.RSITools
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.math.BigDecimal

/**
 * @author : Android-张康
 * created on: 2023/5/4 11:18
 * description: 股票详情页
 */
open class StockDetailsActivity : AppCompatActivity() {

    companion object {

        fun toStockDetailsActivity(context: Context) {
            context.startActivity(Intent(context, StockDetailsActivity::class.java))
        }
    }

    private val mainScope = MainScope()

    private lateinit var mBinding: StockActivityStockDetailsBinding




    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = StockActivityStockDetailsBinding.inflate(layoutInflater)
        setContentView(binding.root)
        mBinding = binding
        binding.setData.setOnClickListener {
            mainScope.launch {
                val number = binding.number.text.toString().toIntOrNull() ?: 300
                binding.kLineView.setKLineData(
                    createTestData(
                        number = number,
                        startYear = 2023,
                        startMonth = 1,
                        startDay = 1,
                        price = 100F
                    )
                )
            }
        }
    }

    private suspend fun createTestData(
        number: Int,
        startYear: Int,
        startMonth: Int,
        startDay: Int,
        price: Float
    ): List<KLineInfo> = withContext(Dispatchers.IO) {
        val mutableList = mutableListOf<KLineInfo>()
        var newDay = startDay
        var newMoth = startMonth
        var newYear = startYear
        var newOpenPrice: Float = price
        val macdTools = MACDTools(12, 26, 9)
        val kdjTools = KDJTools(9, 3, 3)
        val rsiTools = RSITools(6, 12, 24)
        var yesterdayMACD: MACD? = null
        repeat(number) {
            val open = (-10..10).random()
            val height = (open..10).random()
            val lower = (-10..open).random()
            val close = (lower..height).random()
            newDay += 1
            if (newDay >= 31) {
                newDay = 1
                newMoth += 1
            }
            if (newMoth >= 13) {
                newYear += 1
            }
            newOpenPrice *= (open * 0.01F + 1)
            val upOrDown = close * 0.01F
            val closePrice = newOpenPrice * (upOrDown + 1)
            val highPrice = newOpenPrice * (height * 0.01F + 1)
            val lowerPrice = newOpenPrice * (lower * 0.01F + 1)
            val turnover = (10000..20000).random()
            val transactionVolume = (50000..100000).random()
            val macd = macdTools.calculationMACD(closePrice, yesterdayMACD)
            val kLineInfo = KLineInfo(
                date = newYear * 10000 + newMoth * 100 + newDay,
                openPrice = formatFloat(newOpenPrice),
                closePrice = formatFloat(closePrice),
                highPrice = formatFloat(highPrice),
                lowerPrice = if (lowerPrice > newOpenPrice) {
                    formatFloat(newOpenPrice)
                } else {
                    formatFloat(lowerPrice)
                },
                upOrDown = upOrDown,
                adjustFlag = (0..30).random() == 1,
                turnOver = turnover.toLong(),
                macd = macd,
                volume = transactionVolume.toLong(),
                kdj = KDJ(0F, 0F, 0F),
                rsiList = mutableMapOf()
            )
            yesterdayMACD = macd
            mutableList.add(kLineInfo)
            newOpenPrice = closePrice
        }

        var yesterdayKDJ: KDJ? = null
        mutableList.forEachIndexed { index, kLineInfo ->
            Log.i("createTestData", "createTestData: kLineInfo = $kLineInfo")
            val kdj =
                kdjTools.calculationKDJ(
                    mutableList,
                    index,
                    yesterdayKDJ,
                    kLineInfo.closePrice,
                    getMaxPrice = { kLine: KLineInfo ->
                        kLine.highPrice
                    },
                    getMinPrice = { kLine: KLineInfo ->
                        kLine.lowerPrice
                    })
            yesterdayKDJ = kdj
            val rsiMap = rsiTools.calculationRSI(mutableList, index, getRSI = { kLine: KLineInfo ->
                kLine.rsiList
            }, getUpOrDown = { kLine: KLineInfo ->
                kLine.upOrDown
            })
            mutableList[index] = mutableList[index].copy(kdj = kdj, rsiList = rsiMap)
            if (index >= 5) {
                var ma5 = kLineInfo.closePrice
                var turnoverMa5 = kLineInfo.turnOver
                var transactionVolumeMa5 = kLineInfo.volume
                repeat(4) {
                    ma5 += mutableList[index - 1 - it].closePrice
                    turnoverMa5 += mutableList[index - 1 - it].turnOver
                    transactionVolumeMa5 += mutableList[index - 1 - it].volume
                }
                mutableList[index] = mutableList[index].copy(
                    ma5 = formatFloat(ma5 / 5),
                    turnoverMa5 = formatFloat(turnoverMa5 / 5F),
                    volumeMa5 = formatFloat(transactionVolumeMa5 / 5F),
                )
            }
            if (index >= 10) {
                var ma10 = kLineInfo.closePrice
                var turnoverMa10 = kLineInfo.turnOver
                var transactionVolumeMa10 = kLineInfo.volume
                repeat(9) {
                    ma10 += mutableList[index - 1 - it].closePrice
                    turnoverMa10 += mutableList[index - 1 - it].turnOver
                    transactionVolumeMa10 += mutableList[index - 1 - it].volume
                }
                mutableList[index] = mutableList[index].copy(
                    ma10 = formatFloat(ma10 / 10),
                    turnoverMa10 = formatFloat(turnoverMa10 / 10F),
                    volumeMa10 = formatFloat(transactionVolumeMa10 / 10F)
                )
            }
            if (index >= 20) {
                var ma20 = kLineInfo.closePrice
                repeat(10) {
                    ma20 += mutableList[index - 1 - it].closePrice
                }
                mutableList[index] = mutableList[index].copy(ma20 = formatFloat(ma20 / 20))
            }
        }
        return@withContext mutableList
    }

    private fun formatFloat(float: Float): Float {
        return BigDecimal(float.toDouble()).setScale(2, BigDecimal.ROUND_HALF_UP).toFloat()
    }
}